package model;

import java.util.*;

public class Territory{

    private ArrayList<Player> attacker;
    private final int location;
    private final int foodUnit, technologyUnit; 
    private Player owner;
    private HashMap<TechnologyLevel, ArrayList<Troop>> troopList;
    private ArrayList<Territory> neighbors;
        
    //constructor
    public Territory(int _Location, 
    		         int _InitialInfantry, 
    		         Player _Owner, 
    		         int _FoodUnit, 
    		         int _TechnologyUnit){
    	
    	troopList = new HashMap<TechnologyLevel, ArrayList<Troop>>();
    	for (TechnologyLevel level: TechnologyLevel.values())
    	   troopList.put(level, new ArrayList<Troop>());       
    	owner = _Owner;
        attacker = new ArrayList<Player>();
        foodUnit = _FoodUnit;
        technologyUnit = _TechnologyUnit;
        neighbors = new ArrayList<Territory>();
        location = _Location;
        for (int i = 0; i < _InitialInfantry; i++)
            troopList.get(TechnologyLevel.Infantry).add(new Troop(TechnologyLevel.Infantry, owner));
    }
    
    //getter and setter
    public Player getOwner(){return owner;}
    public int getLocation(){return location;}
    public int getFoodUnit(){return foodUnit;}
    public int getTechnologyUnit(){return technologyUnit;}
    public ArrayList<Player> getAttacker(){return attacker;}
    public ArrayList<Territory> getNeighbors(){return neighbors;}
    public ArrayList<Troop> getTroopList(TechnologyLevel level){return troopList.get(level);}
    public int getTroopAmount(Player player){
    	int troopAmount = 0;
    	for(TechnologyLevel level: TechnologyLevel.values())
    	   for(Troop troop : troopList.get(level))
    		  if (troop.getOwner() == player)
    		   troopAmount ++;
    	return troopAmount;
    }
    public int getTroopAmount(TechnologyLevel level, Player player){
    	int troopAmount = 0;
    	for(Troop troop : troopList.get(level))
    		if (troop.getOwner() == player)
    		    troopAmount ++;
    	return troopAmount;
    } 
    public int getUsableTroopAmount(TechnologyLevel level, Player player){
    	int total = 0;
    	for (Troop troop: troopList.get(level))
    		if ((troop.getActioned() == false) && (troop.getOwner() == player)) 
    			total ++;
    	return total;
    }
    private int getUsableTroopAmount(TechnologyLevel level){
    	int total = 0;
    	for (Troop troop: troopList.get(level))
    		if (troop.getActioned() == false)
    			total ++;
    	return total;
    } 
    
    //other methods
    public void addNeighbor(Territory t){neighbors.add(t);}
    public void updateTerritory(Territory t){
        for(TechnologyLevel level: TechnologyLevel.values()){
        	troopList.get(level).clear();
        	for (Troop troop:t.getTroopList(level))
        	   troopList.get(level).add(new Troop(level, troop.getOwner()));
        }
    	if (t.getOwner() != owner){
    		owner.updateTerritory(this);
    		t.getOwner().updateTerritory(this);
    		owner = t.getOwner();
    	}
     } 
    public void addTroop(Troop tr){
    	TechnologyLevel level = tr.getLevel();
    	if (tr.getActioned()) 
    	  troopList.get(level).add(getUsableTroopAmount(level), tr);
    	else 
    	  troopList.get(level).add(0, tr);
    }
    public void removeTroop(TechnologyLevel level, Player player){
    	for (Troop troop: troopList.get(level))
    	   if (troop.getOwner() == player){
    		   troopList.get(level).remove(troop);
    		   return;
    	   }
    }
    public Troop peekTroop(TechnologyLevel level, Player player){
    	for(Troop troop : troopList.get(level))
    	   if (troop.getOwner() == player)
    		return troop;
    	return null;
    }
    
    public void upgradeTroop(TechnologyLevel source, TechnologyLevel destination, int amount, Player player){
    	for (int i = 0; i < amount; i++){
    	  Troop tr = peekTroop(source, player);
    	  removeTroop(source, player);
    	  tr.setLevel(destination);
    	  addTroop(tr);
    	}
    }
    
    public void clearAttacker(){attacker.clear();}
    public void addAttacker(Player p){attacker.add(p);}
    public boolean checkNeighbor(Territory neighbor){
     	if (neighbors.contains(neighbor)) return true;
     	else return false;
    }
}
